#include "ParserXml.h"

ParserXml::ParserXml(){
	this->conexionesTemp = new std::list<ConexionTemp*>;
	this->conexiones = new std::list<Conexion*>;
	this->conexionesTempExternos = new std::list<ConexionesTempExternos*>;
}

ParserXml::~ParserXml(){
	delete conexionesTemp;
	delete conexionesTempExternos;
}

int ParserXml::obtener_Desde_Archivo(char * rutaArchivo, std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> * pListaEntradas,
						std::list<Salida*>* pListaSalidas, std::list<Cable*>* pListaCables,
						std::list<ElementoExterno*>* pListaExternos, std::string * nombreCircuito){
	int nro_id=-1;
	std::string name;
	xmlDocPtr doc;			//doc es un puntero a un archivo xml
	xmlNodePtr node, root;		//node es un puntero a un nodo o tag

	if ((doc = xmlParseFile(rutaArchivo)) == NULL) {
       	return ERROR_PARSEANDO;
  	}
   	//obtengo nodo raiz
	root = xmlDocGetRootElement (doc); //obtengo etiqueta listado de componentes
	name = (char*)  root->name;

	if(name.compare(COMP)==0){
	//leo los tags hasta finalizar
		node = root->xmlChildrenNode;
		do{
			name = (char*)  node->name;

			if(name.compare(CIRCUITO) == 0){
				nro_id = this->agregar_Propiedades_Circuito(node, nombreCircuito);
			}
			else if(name.compare(COMPUERTAS) == 0){
				this->agregar_compuertas(node, pListaCompuertas);
			}
			else if (name.compare(ENTRADAS) == 0){
				this->agregar_entradas(node, pListaEntradas);
			}
			else if (name.compare(SALIDAS) == 0){
				this->agregar_salidas(node, pListaSalidas);
			}
			else if (name.compare(CONEXIONES) == 0){
				this->agregar_conexiones(node,pListaCompuertas, pListaEntradas, pListaSalidas, pListaExternos);
			}
			else if (name.compare(CABLES) == 0){
				this->agregar_cables(node,pListaCables);
			}
			else if (name.compare(ELEMENTOS_EXTERNOS) == 0){
				this->agregar_elementos_externos(node,pListaExternos);
			}
			else{}
			node = node->next;
		}while(node != NULL); //leo siguiente tag
	
		this->mapear_entradas_elementos(pListaCompuertas, pListaEntradas, pListaSalidas);
		this->mapear_elementos_externos(pListaExternos);

		return nro_id;
	}
	std::cerr << "Error en archivo"<< std::endl;
	return -1;
}

int ParserXml::obtener_desde_docPtr(xmlDocPtr p_xml, std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> * pListaEntradas,
			std::list<Salida*>* pListaSalidas, std::list<Cable*>* pListaCables
			,std::list<ElementoExterno*>* pListaExternos, std::string * nombre){

	char * rutaArchivoTemp = (char*)"./XML/temp.xml";
	if (p_xml != NULL){
			 xmlSaveFile(rutaArchivoTemp, p_xml);
			 this->obtener_Desde_Archivo(rutaArchivoTemp,pListaCompuertas,pListaEntradas,pListaSalidas,pListaCables,pListaExternos,nombre);
		     return 0;
	}
	else return 1;
}

void ParserXml::mapear_entradas_elementos(std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> *pListaEntradas 
											, std::list<Salida*> *pListaSalidas){
												
	unsigned int i=0;
	ElementoCircuital * pElemento = NULL;
	Conexion * pConexion = NULL;	
	std::list<ConexionTemp*>::iterator it;
	 
	if(!this->conexionesTemp->empty()){
		it = this->conexionesTemp->begin();

		while( (i < this->conexionesTemp->size())){
			pElemento = this->buscar_por_id((*it)->get_id(), pListaCompuertas, pListaEntradas, pListaSalidas);
			pConexion = this->buscar_por_id_conexion((*it)->get_idConexion_entrada1());

			if(pConexion)  {
				pElemento->set_entrada(pConexion);
			}
			pConexion = this->buscar_por_id_conexion((*it)->get_idConexion_entrada2());

			if(pConexion){
				pElemento->set_entrada(pConexion);
			}
			++it;
			i++;
		}
	}		
}

void ParserXml::mapear_elementos_externos(std::list<ElementoExterno*>* pListaExternos){

	unsigned int i=0, j =0;
	ElementoExterno * pElemento = NULL;
	Conexion * pConexion = NULL;
	std::list<int> L_entradas;
	std::list<ConexionesTempExternos*>::iterator it_ext;
	std::list<int>::iterator it_Lentradas;

	if(!this->conexionesTempExternos->empty()){
		it_ext = this->conexionesTempExternos->begin();
		while( (i < this->conexionesTempExternos->size())){

				pElemento = this->buscar_por_id((*it_ext)->get_id_externo(), pListaExternos);
				L_entradas = (*it_ext)->get_lista_entradas();

				 it_Lentradas = L_entradas.begin();
				 j=0;
				 while(j < L_entradas.size()){

					pConexion = this->buscar_por_id_conexion(*it_Lentradas);
					if(pConexion)  {
						pElemento->set_entrada(pConexion);
					}
					++it_Lentradas;
					j++;
				}

				++it_ext;
				i++;
			}
		}
}

int ParserXml::agregar_Propiedades_Circuito(xmlNodePtr node, std::string * nombre){
	char* c_nro_id;
	*nombre = (char*) xmlGetProp (node, (const xmlChar *)NOMBRE);
	c_nro_id = (char*) xmlGetProp (node, (const xmlChar *)"nro_id");
	return atoi(c_nro_id);
}

void ParserXml::agregar_compuertas(xmlNodePtr node, std::list<Compuerta*> * pListaCompuertas){
	Compuerta * nuevaComp;
	std::string name; 

	xmlNodePtr compuertaXML = node->xmlChildrenNode;
	while(compuertaXML){
		name = (char*)compuertaXML->name;
	
		if((name.compare(AND) == 0)  || (name.compare(OR) == 0)
					 || (name.compare(NOT) == 0) || (name.compare(XOR) == 0) ){  
			nuevaComp = this->setear_compuerta(compuertaXML);

			if (nuevaComp != NULL){
				pListaCompuertas->push_back(nuevaComp);
			}
		}
		compuertaXML = compuertaXML->next;
	}
}
void ParserXml::agregar_entradas(xmlNodePtr node, std::list<Entrada*> * pListaEntradas){
	xmlNodePtr entradaXML = node->xmlChildrenNode;
	Entrada * nuevaEntr;
	std::string name; 

	while(entradaXML){
		name = (char*)entradaXML->name;

		if(name.compare(ENTR) == 0){  
			nuevaEntr = this->setear_entrada(entradaXML);
			if (nuevaEntr){
				pListaEntradas->push_back(nuevaEntr);
			}			
		}
		entradaXML = entradaXML->next;
	}
}

void ParserXml::agregar_salidas(xmlNodePtr node, std::list<Salida*> * pListaSalidas){
	xmlNodePtr salidaXML = node->xmlChildrenNode;
	Salida * nuevaSal;
	std::string name; 

	while(salidaXML){
		name = (char*)salidaXML->name;
		
		if(name.compare(SAL) == 0){  
			nuevaSal = this->setear_salida(salidaXML);
			if (nuevaSal){
				pListaSalidas->push_back(nuevaSal);
			}
		}
		salidaXML = salidaXML->next;
	}
}

void ParserXml::agregar_conexiones(xmlNodePtr node, std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> * pListaEntradas
											, std::list<Salida*> * pListaSalidas,std::list<ElementoExterno*>* pListaExternos){
	xmlNodePtr conexionXML = node->xmlChildrenNode;
	Conexion * nuevaCon;
	std::string name; 

	while(conexionXML){
		name = (char*)conexionXML->name;
		
		if(name.compare(CONEX) == 0){  
			nuevaCon = this->setear_conexion(conexionXML,pListaCompuertas, pListaEntradas, pListaSalidas, pListaExternos);
	// Agrego la conexion a una lista de CONEXIONES que cuando termine de cargar el
	// xml hay que agregarla a los componentes

			if (nuevaCon != NULL)
           				this->conexiones->push_back(nuevaCon);
		}
		conexionXML = conexionXML->next;
	}
}

void ParserXml::agregar_cables(xmlNodePtr node, std::list<Cable*> * pListaCables){
	xmlNodePtr cableXML = node->xmlChildrenNode;
	Cable * nuevoCable;
	std::string name;

	while(cableXML){
		name = (char*)cableXML->name;

		if(name.compare(CABLE) == 0){
			nuevoCable = this->setear_cable(cableXML);

			if (nuevoCable != NULL)
					pListaCables->push_back(nuevoCable);
		}
		cableXML = cableXML->next;
	}
}

void ParserXml::agregar_elementos_externos(xmlNodePtr node,std::list<ElementoExterno*>* pListaExternos){
	xmlNodePtr externoXML = node->xmlChildrenNode;
	ElementoExterno * nuevoExterno;
	std::string name;

	Cliente * cliente = new Cliente();

	while(externoXML){
		name = (char*)externoXML->name;
		if(name.compare(EXTERNO) == 0){
			nuevoExterno = this->setear_elemento_externo(externoXML, pListaExternos, cliente/*, pListaCables*/);

			if (nuevoExterno != NULL);
				pListaExternos->push_back(nuevoExterno);
		}
		externoXML = externoXML->next;
	}
}

ElementoExterno* ParserXml::setear_elemento_externo(xmlNodePtr externoXML, std::list<ElementoExterno*>* pListaExternos,
												Cliente * cliente){
	ElementoExterno * nuevoExterno=NULL;
	char * pos_X, * pos_Y, *id=(char*)"", *port, *ip, *cant_ent, *cant_sal, *id_entrada,*angulo;
	std::string name, nameTag, nombreElemento, Entrada,nameEnt;

	xmlNodePtr hijoExternoXML = externoXML->xmlChildrenNode;
	while(hijoExternoXML){
		nameTag = (char*)hijoExternoXML->name;

		if(nameTag.compare(DATOS) == 0){
				nombreElemento = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)NOMBRE);
				id = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)ID);
				pos_X = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)POS_X);
				pos_Y = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)POS_Y);
				port = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)PORT);
				ip = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)IP);
				cant_ent = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)CANT_ENT);
				cant_sal = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)CANT_SAL);
				angulo = (char*) xmlGetProp (hijoExternoXML, (const xmlChar *)ANGULO);

				nuevoExterno = new ElementoExterno(atoi(pos_X), atoi(pos_Y),atoi(id),
							ip,atoi(port),cliente, atoi(cant_ent), atoi(cant_sal),nombreElemento);
				nuevoExterno->set_angulo(atoi(angulo));
			}
		else if(nameTag.compare(ENTRADAS) == 0){
				xmlNodePtr entradasExternoXML = hijoExternoXML->xmlChildrenNode;

				ConexionesTempExternos * c_temp = new ConexionesTempExternos(atoi(id));
				while(entradasExternoXML){
						nameEnt = (char*)entradasExternoXML->name;

						if(nameEnt.compare(ENTR) == 0){
							id_entrada = (char*) xmlGetProp (entradasExternoXML, (const xmlChar *)ENTRADA);

							c_temp->agregar_conexionTemp_externos(atoi(id_entrada));

						}
						entradasExternoXML = entradasExternoXML->next;
					}
					this->conexionesTempExternos->push_back(c_temp);
				}
				hijoExternoXML = hijoExternoXML->next;
	}
	return nuevoExterno;
}

Cable * ParserXml::setear_cable(xmlNodePtr cableXML/*, pListaCables*/){
	std::string name, nro_id;
	char * pos_X, * pos_Y;
	Cable * nuevoCable = new Cable();

	xmlNodePtr quiebreXML = cableXML->xmlChildrenNode;
	nro_id = (char*) xmlGetProp (cableXML, (const xmlChar *)"nro_id");
	nuevoCable->set_id(atoi(nro_id.c_str()));

	while(quiebreXML){
		name = (char*)quiebreXML->name;

		if(name.compare(QUIEBRE) == 0){
			pos_X = (char*) xmlGetProp (quiebreXML, (const xmlChar *)POS_X);
			pos_Y = (char*) xmlGetProp (quiebreXML, (const xmlChar *)POS_Y);

			nuevoCable->agregar_punto(atoi(pos_X), atoi(pos_Y));
		}
		quiebreXML = quiebreXML->next;
	}
	return nuevoCable;
}


Conexion * ParserXml::setear_conexion(xmlNodePtr conexionXML, std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> * pListaEntradas
											, std::list<Salida*> * pListaSalidas ,std::list<ElementoExterno*>* pListaExternos){
	Conexion * nuevaCon = NULL;
	ElementoCircuital * pEmisor =NULL, *pReceptor = NULL; 
	std::string name;
	char* id,* nro_salida,* nro_entrada, *emisor, *receptor;

	name = (char*)conexionXML->name;
	id = (char*) xmlGetProp (conexionXML, (const xmlChar *)ID);
	nro_entrada = (char*) xmlGetProp (conexionXML, (const xmlChar *)NRO_ENTRADA);
	nro_salida = (char*) xmlGetProp (conexionXML, (const xmlChar *)NRO_SALIDA);
	emisor = (char*) xmlGetProp (conexionXML, (const xmlChar *)EMISOR);
	receptor = (char*) xmlGetProp (conexionXML, (const xmlChar *)RECEPTOR);
	
	if(receptor != NULL ){
		pReceptor =	this->buscar_por_id(atoi(receptor),pListaCompuertas, pListaEntradas, pListaSalidas);
	}
	if (receptor != NULL && pReceptor == NULL){
		pReceptor = this->buscar_por_id(atoi(receptor),pListaExternos);
	}
	if(emisor != NULL ){
		pEmisor = this->buscar_por_id(atoi(emisor),pListaCompuertas, pListaEntradas, pListaSalidas);
	}
	if (emisor != NULL && pEmisor == NULL){
		pEmisor = this->buscar_por_id(atoi(emisor),pListaExternos);
	}

	nuevaCon = new Conexion(atoi(id),pEmisor,atoi(nro_entrada),atoi(nro_salida),pReceptor); //hacer atois correspondientes.
	return nuevaCon;
}

ElementoCircuital * ParserXml::buscar_por_id(int id_a_buscar, std::list<Compuerta*> * pListaCompuertas, 
									std::list<Entrada*> * pListaEntradas, std::list<Salida*> * pListaSalidas){
	std::list<Entrada*>::iterator it_entrada;
	std::list<Salida*>::iterator it_salida;
	std::list<Compuerta*>::iterator it_compuerta;
	bool enc_entrada = false;
	bool enc_salida = false;
	bool enc_compuerta = false;
	unsigned int i= 0;
	 
	if(!pListaCompuertas->empty()){
		it_compuerta = pListaCompuertas->begin();

		while( (i < pListaCompuertas->size()) && (!enc_compuerta)){
			if((*it_compuerta)->get_id() == id_a_buscar){
			 enc_compuerta=true;
			}
			else{ 
				++it_compuerta;
				i++;
			}
		}		
	}
	if(!pListaEntradas->empty() && (!enc_compuerta)){
		i=0;
		it_entrada = pListaEntradas->begin();
		
		while((i < pListaEntradas->size()) && (!enc_entrada)){
			if((*it_entrada)->get_id() == id_a_buscar){
				 enc_entrada=true;
			}
			else{ 
				++it_entrada;
				i++;
			}
		}
	}
	if(!pListaSalidas->empty() && (!enc_entrada) && (!enc_compuerta)){
		i=0;
		it_salida = pListaSalidas->begin();
		while( (i < pListaSalidas->size()) && (!enc_salida)){
			if((*it_salida)->get_id() == id_a_buscar){
			 enc_salida=true;
			}
			else{ 
				++it_salida;
				i++;
			}
		}
	}
	if (enc_entrada){
		 return (*it_entrada);
	}
	else if (enc_salida){
		 return (*it_salida);
	}
	else if (enc_compuerta){
		 return (*it_compuerta);
	}
	else {	
		return NULL;
	}
}

ElementoExterno* ParserXml::buscar_por_id(int id_a_buscar, std::list<ElementoExterno*>* pListaExternos){
	unsigned int i=0;
	std::list<ElementoExterno*>::iterator it_externo;
	bool enc = false;

	if(!pListaExternos->empty()){
		it_externo = pListaExternos->begin();
		while( (i < pListaExternos->size()) && (!enc)){
			if((*it_externo)->get_id() == id_a_buscar){
				enc=true;
			}
			else{
				++it_externo;
				i++;
			}
		}
	}
	if(enc) return (*it_externo);
	else return NULL;
}

Conexion * ParserXml::buscar_por_id_conexion(int id_conexion){
	std::list<Conexion*>::iterator it;
	bool enc = false;
	unsigned int i= 0;
	 
	if(!this->conexiones->empty()){
		it = this->conexiones->begin();

		while( (i < this->conexiones->size()) && (!enc)){
			if((*it)->get_id() == id_conexion){
			 enc=true;
			}
			else{ 
				++it;
				i++;
			}
		}		
	}
	if (enc){
		return (*it);
	}
	else {	
		return NULL;
	}
}

Compuerta * ParserXml::setear_compuerta(xmlNodePtr compuertaXML){
	Compuerta * nuevaComp = NULL;
	ConexionTemp * nuevaConexion;
	std::string name;
	char* id,* time, *entrada_1, *entrada_2, *posX,*posY,*angulo;

	name = (char*)compuertaXML->name;
	id = (char*) xmlGetProp (compuertaXML, (const xmlChar *)ID);
	time = (char*) xmlGetProp (compuertaXML, (const xmlChar *)TIME);
	entrada_1 = (char*) xmlGetProp (compuertaXML, (const xmlChar *)ENTRADA_1);
	entrada_2 = (char*) xmlGetProp (compuertaXML, (const xmlChar *)ENTRADA_2);
//seteo los valores que necesita la interfaz
	posX= (char*) xmlGetProp (compuertaXML, (const xmlChar *)POS_X);
	posY = (char*) xmlGetProp (compuertaXML, (const xmlChar *)POS_Y);
	angulo = (char*) xmlGetProp (compuertaXML, (const xmlChar *)ANGULO);
	
	if(name.compare(AND) == 0){
		nuevaComp = new And(atoi(posX),atoi(posY),atoi(id), atoi(time));
	}
	else if(name.compare(OR) == 0)
		nuevaComp = new Or(atoi(posX),atoi(posY),atoi(id), atoi(time));
	else if(name.compare(XOR) == 0)
		nuevaComp = new Xor(atoi(posX),atoi(posY),atoi(id), atoi(time));
	else if(name.compare(NOT) == 0)
		nuevaComp = new Not(atoi(posX),atoi(posY),atoi(id), atoi(time));
	
	if(nuevaComp){
		nuevaComp->set_angulo(atoi(angulo));
		nuevaConexion = new ConexionTemp(atoi(id),atoi(entrada_1),atoi(entrada_2)); 
		if(nuevaConexion)
			this->conexionesTemp->push_back(nuevaConexion);	
	}
	return nuevaComp; //devuelvo compuerta creada de xml
}

Entrada * ParserXml::setear_entrada(xmlNodePtr entradaXML){
	Entrada * nuevaEntr = NULL;
	std::string name, nombreEntrada;
	char * id, *estado, *posX,*posY,*angulo;
	
	name = (char*)entradaXML->name;
	nombreEntrada = (char*) xmlGetProp (entradaXML, (const xmlChar *)NOMBRE);
	id = (char*) xmlGetProp (entradaXML, (const xmlChar *)ID);
	estado = (char*) xmlGetProp (entradaXML, (const xmlChar *)ESTADO);
//seteo los valores que necesita la interfaz
	posX= (char*) xmlGetProp (entradaXML, (const xmlChar *)POS_X);
	posY = (char*) xmlGetProp (entradaXML, (const xmlChar *)POS_Y);
	angulo = (char*) xmlGetProp (entradaXML, (const xmlChar *)ANGULO);
	
	if(name.compare(ENTR) == 0){
		nuevaEntr = new Entrada(atoi(posX),atoi(posY),atoi(id), nombreEntrada);
		if(atoi(estado)){
			nuevaEntr->set_estado(true);
		}
		else{ 	
			nuevaEntr->set_estado(false);
		}
		nuevaEntr->set_angulo(atoi(angulo));
	}
	return nuevaEntr;
}

Salida * ParserXml::setear_salida(xmlNodePtr salidaXML){
	Salida * nuevaSal = NULL;
	std::string name, nombreSalida;
	char * id, *entrada, *posX,*posY,*angulo;
	ConexionTemp * nuevaConexion;
			
	name = (char*)salidaXML->name;
	nombreSalida = (char*) xmlGetProp (salidaXML, (const xmlChar *)NOMBRE);
	id = (char*) xmlGetProp (salidaXML, (const xmlChar *)ID);
	entrada = (char*) xmlGetProp (salidaXML, (const xmlChar *)ENTRADA);
//seteo los valores que necesita la interfaz
	posX= (char*) xmlGetProp (salidaXML, (const xmlChar *)POS_X);
	posY = (char*) xmlGetProp (salidaXML, (const xmlChar *)POS_Y);
	angulo = (char*) xmlGetProp (salidaXML, (const xmlChar *)ANGULO);

	if(name.compare(SAL) == 0){
		nuevaSal = new Salida(atoi(posX),atoi(posY),atoi(id), nombreSalida);
	
		nuevaSal->set_angulo(atoi(angulo));
    	nuevaConexion = new ConexionTemp(atoi(id),atoi(entrada));
		this->conexionesTemp->push_back(nuevaConexion);
	}
	return nuevaSal;
}

int ParserXml::persistir_En_Archivo(char * rutaArchivo, std::list<Compuerta*> * pListaCompuertas, std::list<Entrada*> * pListaEntradas,
						std::list<Salida*>* pListaSalidas, std::list<Cable*>* pListaCables,
						std::list<ElementoExterno*>* pListaExternos, std::string * nombre, int nro_id){

	std::list<Conexion*>* pListaConexiones = new std::list<Conexion*>;
	xmlNodePtr root, node;
	xmlDocPtr doc;

	doc = xmlNewDoc((xmlChar*)"1.0");
	root = xmlNewDocNode(doc, NULL,(xmlChar*)COMP ,NULL );
	xmlDocSetRootElement(doc, root);

	node = xmlNewChild(root, NULL, (xmlChar*)CIRCUITO,NULL);
	this->guardar_propiedades_circuito(node, nombre, nro_id);

	node = xmlNewChild(root, NULL, (xmlChar*)COMPUERTAS,NULL);
	this->guardar_compuertas(node, pListaCompuertas, pListaConexiones);

	node = xmlNewChild(root, NULL, (xmlChar*)ENTRADAS,NULL);
	this->guardar_entradas(node, pListaEntradas, pListaConexiones);

	node = xmlNewChild(root, NULL, (xmlChar*)SALIDAS,NULL);
	this->guardar_salidas(node, pListaSalidas, pListaConexiones);

	node = xmlNewChild(root, NULL, (xmlChar*)ELEMENTOS_EXTERNOS,NULL);
	this->guardar_elementos_externos(node, pListaExternos, pListaConexiones);

	node = xmlNewChild(root, NULL,(xmlChar*) CONEXIONES,NULL);
	this->guardar_conexiones(node, pListaConexiones);

	node = xmlNewChild(root, NULL,(xmlChar*) CABLES,NULL);
	this->guardar_cables(node, pListaCables);

	if(xmlSaveFile(rutaArchivo, doc)){
		return 1;
	}
	else return 0;
}

void ParserXml::guardar_propiedades_circuito(xmlNodePtr node, std::string * nombre,int nro_id){
	if(nombre!=NULL){
		char buffer[10];
		xmlSetProp(node,(xmlChar*)NOMBRE, (xmlChar*)nombre->c_str());
		sprintf (buffer, "%d", nro_id);
		xmlSetProp(node,(xmlChar*)"nro_id", (xmlChar*)buffer);
	}
}

void ParserXml::guardar_compuertas(xmlNodePtr root,std::list<Compuerta*>* pListaCompuertas,
								std::list<Conexion*>* pListaConexiones){
	std::list<Compuerta*>::iterator it;
	int entrada2_not = -1;
	int entrada1_not = -1;
	char buffer[10];
	xmlNodePtr node = NULL;
	unsigned int i= 0;
	 
	if(!pListaCompuertas->empty()){
		it = pListaCompuertas->begin();
		while( (i < pListaCompuertas->size()) ){
			int tipo = (*it)->get_tipo();
			//cambiar por case
			switch (tipo){
				case 3 :{
					node = xmlNewChild(root, NULL, (xmlChar*)AND, NULL);
					break;
				}
				case 4:{
					node = xmlNewChild(root, NULL, (xmlChar*)NOT, NULL);
					break;
				}
				case 5 : {
					node = xmlNewChild(root, NULL, (xmlChar*)OR, NULL);
					break;
				}
				case 6 : {
					node = xmlNewChild(root, NULL, (xmlChar*)XOR, NULL);
					break;
				}
			}
			sprintf (buffer, "%d", (*it)->get_id());			
			xmlSetProp(node,(xmlChar*)ID, (xmlChar*)buffer);
			
			sprintf (buffer, "%d", (*it)->get_tiempo());			
			xmlSetProp(node,(xmlChar*)TIME, (xmlChar*)buffer);			

			if((*it)->get_entrada1()){
				sprintf (buffer, "%d", (*it)->get_entrada1()->get_id());
				xmlSetProp(node,(xmlChar*)ENTRADA_1, (xmlChar*)buffer);
			}
			else {
				sprintf (buffer, "%d", entrada1_not);
				xmlSetProp(node,(xmlChar*)ENTRADA_1, (xmlChar*)buffer);
			}
			if(tipo != 4 && (*it)->get_entrada2()){  //si es distinto de NOT
				sprintf (buffer, "%d",  (*it)->get_entrada2()->get_id());			
				xmlSetProp(node,(xmlChar*)ENTRADA_2, (xmlChar*)buffer);
			}
			else {  //si es NOT 
				sprintf (buffer, "%d", entrada2_not);			
				xmlSetProp(node,(xmlChar*)ENTRADA_2, (xmlChar*)buffer);
			}
			this->setearPropDeInterfaz(node, (*it));
		
			if((*it)->get_entrada1()) pListaConexiones->push_back((*it)->get_entrada1());
			if((*it)->get_entrada2()) pListaConexiones->push_back((*it)->get_entrada2());
			++it;
			i++;
		}		
	}
}

void ParserXml::guardar_entradas(xmlNodePtr root,std::list<Entrada*>* pListaEntradas,
										std::list<Conexion*>* pListaConexiones){
	std::list<Entrada*>::iterator it;
	char buffer[10];
	xmlNodePtr node;
	unsigned int i= 0;

	if(!pListaEntradas->empty()){
		it = pListaEntradas->begin();
		while( (i < pListaEntradas->size()) ){
			node = xmlNewChild(root, NULL, (xmlChar*)ENTR, NULL);
		
			xmlSetProp(node,(xmlChar*)NOMBRE, (xmlChar*)(*it)->get_nombre().c_str());

			sprintf (buffer, "%d", (*it)->get_id());			
			xmlSetProp(node,(xmlChar*)ID, (xmlChar*)buffer);
			
			sprintf (buffer, "%d", (*it)->get_estado());			
			xmlSetProp(node,(xmlChar*)ESTADO, (xmlChar*)buffer);
			
			this->setearPropDeInterfaz(node, (*it));
	
			++it;
			i++;
		}
	}
}

void ParserXml::guardar_salidas(xmlNodePtr root,std::list<Salida*>* pListaSalidas,
		std::list<Conexion*>* pListaConexiones){
		
	std::list<Salida*>::iterator it;
	char buffer[10];
	xmlNodePtr node;
	unsigned int i= 0;
	unsigned int salida_not = -1;

	if(!pListaSalidas->empty()){
		it = pListaSalidas->begin();

		while( (i < pListaSalidas->size()) ){
			node = xmlNewChild(root, NULL, (xmlChar*)SAL, NULL);			 
						
			xmlSetProp(node,(xmlChar*)NOMBRE, (xmlChar*)(*it)->get_nombre().c_str());

			sprintf (buffer, "%d", (*it)->get_id());			
			xmlSetProp(node,(xmlChar*)ID, (xmlChar*)buffer);
			
			if((*it)->get_entrada()){
				sprintf (buffer, "%d", (*it)->get_entrada()->get_id());
				xmlSetProp(node,(xmlChar*)ENTRADA, (xmlChar*)buffer);
			}
			else {
						sprintf (buffer, "%d", salida_not);
						xmlSetProp(node,(xmlChar*)ENTRADA, (xmlChar*)buffer);
			}
			this->setearPropDeInterfaz(node, (*it));

			if((*it)->get_entrada()) pListaConexiones->push_back((*it)->get_entrada());

			++it;
			i++;
		}
	}
}
void ParserXml::setearPropDeInterfaz(xmlNodePtr node,ElementoCircuital * pGenerico){
		char buffer[10];
		sprintf (buffer, "%d",  pGenerico->get_posicion_x());
		xmlSetProp(node,(xmlChar*)POS_X, (xmlChar*)buffer);

		sprintf (buffer, "%d",  pGenerico->get_posicion_y());
		xmlSetProp(node,(xmlChar*)POS_Y, (xmlChar*)buffer);

		sprintf (buffer, "%d",  pGenerico->get_angulo());
		xmlSetProp(node,(xmlChar*)ANGULO, (xmlChar*)buffer);
}

void ParserXml::guardar_conexiones(xmlNodePtr root,std::list<Conexion*>* pListaConexiones){
	std::list<Conexion*>::iterator it;
	char buffer[10];
	xmlNodePtr node;
	unsigned int i= 0;

	if(!pListaConexiones->empty()){
		it = pListaConexiones->begin();

		while( (i < pListaConexiones->size()) ){
			node = xmlNewChild(root, NULL, (xmlChar*)CONEX, NULL);			 

			sprintf (buffer, "%d", (*it)->get_id());			
			xmlSetProp(node,(xmlChar*)ID, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_nro_entrada());
			xmlSetProp(node,(xmlChar*)NRO_ENTRADA, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_nro_salida());
			xmlSetProp(node,(xmlChar*)NRO_SALIDA, (xmlChar*)buffer);
			
			sprintf (buffer, "%d", (*it)->get_emisor()->get_id());			
			xmlSetProp(node,(xmlChar*)EMISOR, (xmlChar*)buffer);	
			
			sprintf (buffer, "%d", (*it)->get_receptor()->get_id());			
			xmlSetProp(node,(xmlChar*)RECEPTOR, (xmlChar*)buffer);						
			
			++it;
			i++;
		}
	}
}

void ParserXml::guardar_cables(xmlNodePtr root,std::list<Cable*>* pListaCables){
	std::list<Cable*>::iterator it;
	std::list<PuntoQuiebre*>::iterator it_quiebres;
	std::list<PuntoQuiebre*> listaQuiebres;
	char buffer[10];
	xmlNodePtr nodeCable, nodeQuiebre;
	unsigned int i= 0, j=0;

	if(!pListaCables->empty()){
		it = pListaCables->begin();
		while( (i < pListaCables->size()) ){
			nodeCable = xmlNewChild(root, NULL, (xmlChar*)CABLE, NULL);

			sprintf (buffer, "%d", (*it)->get_id());
			xmlSetProp(nodeCable,(xmlChar*)"nro_id", (xmlChar*)buffer);

			listaQuiebres = (*it)->get_lista();

			if( !listaQuiebres.empty() ){
				it_quiebres = listaQuiebres.begin();

				while( (j < listaQuiebres.size()) ){
					nodeQuiebre = xmlNewChild(nodeCable, NULL, (xmlChar*)QUIEBRE, NULL);

					sprintf (buffer, "%d", (*it_quiebres)->get_x());
					xmlSetProp(nodeQuiebre,(xmlChar*)POS_X, (xmlChar*)buffer);

					sprintf (buffer, "%d", (*it_quiebres)->get_y());
					xmlSetProp(nodeQuiebre,(xmlChar*)POS_Y, (xmlChar*)buffer);

					++it_quiebres;
					j++;
				}
			}
			j = 0;
			++it;
			i++;
		}
	}
}

void ParserXml::guardar_elementos_externos(xmlNodePtr root, std::list<ElementoExterno*>* pListaExternos,
					std::list<Conexion*> * pListaConexiones	){
	xmlNodePtr nodeExterno, nodeDatos, nodeEntradas, nodeEnt ;
	std::list<Conexion*> L_entradas;
	std::list<ElementoExterno*>::iterator it;
	std::list<Conexion*>::iterator it_entradas;
	char buffer[20];
	xmlNodePtr node = NULL;
	unsigned int i= 0, j=0;

	if(!pListaExternos->empty()){
		it = pListaExternos->begin();

		while( (i < pListaExternos->size()) ){
			nodeExterno = xmlNewChild(root, NULL, (xmlChar*)EXTERNO, NULL);

			nodeDatos = xmlNewChild(nodeExterno, NULL, (xmlChar*)DATOS, NULL);

			xmlSetProp(nodeDatos,(xmlChar*)NOMBRE, (xmlChar*)((*it)->get_nombre()).c_str());

			sprintf (buffer, "%d", (*it)->get_id());
			xmlSetProp(nodeDatos,(xmlChar*)ID, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_puerto());
			xmlSetProp(nodeDatos,(xmlChar*)PORT, (xmlChar*)buffer);

			xmlSetProp(nodeDatos,(xmlChar*)IP, (xmlChar*)((*it)->get_ip()).c_str());

			sprintf (buffer, "%d", (*it)->get_cant_entradas());
			xmlSetProp(nodeDatos,(xmlChar*)CANT_ENT, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_cant_salidas());
			xmlSetProp(nodeDatos,(xmlChar*)CANT_SAL, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_posicion_x());
			xmlSetProp(nodeDatos,(xmlChar*)POS_X, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_posicion_y());
			xmlSetProp(nodeDatos,(xmlChar*)POS_Y, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_angulo());
			xmlSetProp(nodeDatos,(xmlChar*)ANGULO, (xmlChar*)buffer);

			sprintf (buffer, "%d", (*it)->get_cant_salidas());
			xmlSetProp(nodeDatos,(xmlChar*)CANT_SAL, (xmlChar*)buffer);

			this->setearPropDeInterfaz(node, (*it));
			nodeEntradas = xmlNewChild(nodeExterno, NULL, (xmlChar*)ENTRADAS, NULL);

			L_entradas = (*it)->get_lista_entradas();

			if(!L_entradas.empty()){
				it_entradas = L_entradas.begin();
				j = 0;
					while((j < L_entradas.size())){
						if(*it_entradas != NULL){
							nodeEnt = xmlNewChild(nodeEntradas, NULL, (xmlChar*)ENTR, NULL);
							sprintf (buffer, "%d", (*it_entradas)->get_id());
							xmlSetProp(nodeEnt,(xmlChar*)ENTRADA, (xmlChar*)buffer);
							pListaConexiones->push_back(*it_entradas);
						}
						else {}
						++it_entradas;
						j++;
					}
			}
			++it;
			i++;
		}
	}
}
